package Collections.predecessor;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @author Brook
 */
public class MapDemo {

    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        System.out.println(map.isEmpty());
        map.put("东哥", 28);
        map.put("西哥", 88);
        System.out.println(map.keySet());
        System.out.println(map.values());

        //遍历方式
        //1.Streams API多线程
        map.entrySet().parallelStream().forEach((entry) -> {
            System.out.println(entry.getKey());
            System.out.println(entry.getValue());
        });
        System.out.println("-----------------2.Streams API 单线程-----------------");
        //2.Streams API 单线程
        map.entrySet().stream().filter((f) -> 28 != f.getValue()).forEach((entry) -> {
            System.out.println(entry.getKey());
            System.out.println(entry.getValue());
        });

        System.out.println("--------------------------------");
        //3.Lambda
        map.forEach((key, value) -> {
            System.out.println(key);
            System.out.println(value);
        });

        System.out.println("---------------------------------");
        //4.ForEach KeySet
        for (String key : map.keySet()) {
            System.out.println(key);
            System.out.println(map.get(key));
        }
        System.out.println("--------------------------------");
        //5.ForEach EntrySet
        for (Map.Entry<String,Integer> entry : map.entrySet()) {
            System.out.println(entry.getKey());
            System.out.println(entry.getValue());
        }
        System.out.println("----------------------------------");
        //6.迭代器KeySet
        Iterator<String> iterator = map.keySet().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            System.out.println(key);
            System.out.println(map.get(key));
        }
        System.out.println("----------------------------------");
        //7.迭代器EntrySet
        Iterator<Map.Entry<String, Integer>> iterator1 = map.entrySet().iterator();
        while (iterator1.hasNext()) {
            Map.Entry<String, Integer> entry = iterator1.next();
            System.out.println(entry.getKey());
            System.out.println(entry.getValue());
        }

        //7种遍历方式性能比较
        /**
         * 从以上结果可以看出 entrySet 的性能比 keySet 的性能高出了一倍之多，因此我们应该尽量使用 entrySet  来实现 Map 集合的遍历。
         *
         * EntrySet 之所以比 KeySet 的性能高是因为，KeySet 在循环时使用了 map.get(key)，而 map.get(key)
         * 相当于又遍历了一遍 Map 集合去查询 key 所对应的值。为什么要用“又”这个词？那是因为在使用迭代器或者 for 循环时，
         * 其实已经遍历了一遍 Map 集合了，因此再使用 map.get(key) 查询时，相当于遍历了两遍。
         *
         * 而 EntrySet 只遍历了一遍 Map 集合，之后通过代码“Entry<Integer, String> entry = iterator.next()”把对象的 key
         * 和 value 值都放入到了 Entry 对象中，因此再获取 key 和 value 值时就无需再遍历 Map 集合，只需要从 Entry 对象中取值就可以了。
         *
         * 所以，EntrySet 的性能比 KeySet 的性能高出了一倍，因为 KeySet 相当于循环了两遍 Map 集合，而 EntrySet 只循环了一遍。
         *
         */
        //安全性
        /**
         * 我们不能在遍历中使用集合 map.remove() 来删除数据，这是非安全的操作方式，但我们可以使用迭代器的 iterator.remove()
         * 的方法来删除数据，这是安全的删除集合的方式。同样的我们也可以使用 Lambda 中的 removeIf 来提前删除数据，
         * 或者是使用 Stream 中的 filter 过滤掉要删除的数据进行循环，这样都是安全的，当然我们也可以在 for 循环前删除数据在遍历也是线程安全的。
         */
        /**
         *  HashMap 4 种遍历方式：迭代器、for、lambda、stream，以及具体的 7 种遍历方法，
         *  综合性能和安全性来看，我们应该尽量使用迭代器（Iterator）来遍历 EntrySet 的遍历方式来操作 Map 集合，这样就会既安全又高效了。
         */

        System.out.println(map.containsKey("西哥"));
    }
}
